{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "hqCTP5D55YuD"
   },
   "source": [
    "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/googlecolab/colabtools/blob/master/notebooks/Fine-tuning-CodeLlama_demo.ipynb)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "b3HJ07DT_sgw"
   },
   "outputs": [],
   "source": [
    "import os\n",
    "os.environ['MAX_SPLIT_SIZE_GB'] = '32'\n",
    "import torch\n",
    "device = torch.device(\"cuda\")  # Make sure you're using the correct device\n",
    "mem_info = torch.cuda.memory_stats(device=device)\n",
    "memory_usage_bytes = mem_info.get(\"allocated_bytes.all.current\")\n",
    "torch.cuda.empty_cache()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "HDPjMVKT3yre"
   },
   "source": [
    "#Downloading Dependencies"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#!pip install  -i https://pypi.tuna.tsinghua.edu.cn/simple transformers\n",
    "#!pip install bitsandbytes\n",
    "#!pip install /home/rlc/下载/peft-main\n",
    "#!pip install  -i https://pypi.tuna.tsinghua.edu.cn /home/rlc/下载/accelerate-main\n",
    "#!pip install  -i https://pypi.tuna.tsinghua.edu.cn accelerate\n",
    "#!pip install git+https://github.com/huggingface/transformers.git@refs/pull/25740/head accelerate\n",
    "#!pip install -q -U git+https://github.com/huggingface/peft.git\n",
    "#!pip install git+https://github.com/huggingface/accelerate\n",
    "#!pip install  -i https://pypi.tuna.tsinghua.edu.cn/simple trl\n",
    "#!pip install  -i https://pypi.tuna.tsinghua.edu.cn/simple einops wandb"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "bz0-DGpL3s0r"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/rlc/miniconda3/envs/cu121/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n"
     ]
    }
   ],
   "source": [
    "import transformers\n",
    "from transformers import AutoModelForCausalLM , AutoTokenizer , BitsAndBytesConfig , HfArgumentParser,TrainingArguments, pipeline, logging\n",
    "from peft import PeftModel,LoraConfig,PeftModelForCausalLM\n",
    "from trl import SFTTrainer\n",
    "from datasets import load_dataset"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "U63W7WrtlZPt"
   },
   "source": [
    "#Load dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "id": "vGNiWxH8lYpD"
   },
   "outputs": [],
   "source": [
    "dataset = load_dataset(\"/home/rlc/搞着玩/huggingface/datasets/nickrosh___evol-instruct-code-80k-v1/default/0.0.0/3ae930c20d5496e2c8386872d5628c45f6957db4/\", split = \"train\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "1ypGo28yFCD3"
   },
   "source": [
    "#Tokenize the LLM"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "id": "wRgUebO8_q72"
   },
   "outputs": [],
   "source": [
    "\n",
    "model_name = \"/home/rlc/搞着玩/huggingface/hub/models--codellama--CodeLlama-7b-Instruct-hf/snapshots/22cb240e0292b0b5ab4c17ccd97aa3a2f799cbed/\"\n",
    "\n",
    "#model_name = \"codellama/CodeLlama-7b-Instruct-hf\"\n",
    "tokenizer = AutoTokenizer.from_pretrained(model_name)\n",
    "# Fine-tuned model name\n",
    "new_model = \"Luffy/codellama-2-7b-Instruct-hf-Fine-tuned\"\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "id": "47lXlkWE_q3P"
   },
   "outputs": [],
   "source": [
    "training_config = {\n",
    "    \"model\": {\n",
    "        \"pretrained_name\": model_name,\n",
    "        \"max_length\" : 2048#进行了修改\n",
    "       # \"max_length\" : 4096#进行了修改\n",
    "    },\n",
    "    \"datasets\": {\n",
    "        # \"use_hf\": use_hf,\n",
    "        \"path\": dataset\n",
    "    },\n",
    "    \"verbose\": True # a boolean indicating whether to output detailed information during the process.\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "id": "cV0Mhz-X_qy8"
   },
   "outputs": [],
   "source": [
    "def tokenize_function(examples):\n",
    "    if \"question\" in examples and \"answer\" in examples:\n",
    "      text = examples[\"question\"][0] + examples[\"answer\"][0]\n",
    "    elif \"input\" in examples and \"output\" in examples:\n",
    "      text = examples[\"input\"][0] + examples[\"output\"][0]\n",
    "    elif \"instruction\" in examples and \"response\" in examples:\n",
    "      text = examples[\"instruction\"][0] + examples[\"response\"][0]\n",
    "    elif \"instruction\" in examples and \"completion\" in examples:\n",
    "      text = examples[\"instruction\"][0] + examples[\"completion\"][0]\n",
    "    elif \"instruction\" in examples and \"output\" in examples:\n",
    "      text = examples[\"instruction\"][0] + examples[\"output\"][0]\n",
    "    else:\n",
    "      text = examples[\"text\"][0]\n",
    "    tokenizer.pad_token = tokenizer.eos_token\n",
    "    tokenized_inputs = tokenizer(\n",
    "        text,\n",
    "        return_tensors=\"np\",\n",
    "        padding=True,\n",
    "    )\n",
    "\n",
    "    max_length = min(\n",
    "        tokenized_inputs[\"input_ids\"].shape[1],\n",
    "        2048#4096#2048\n",
    "    )\n",
    "    tokenizer.truncation_side = \"left\"\n",
    "    tokenized_inputs = tokenizer(\n",
    "        text,\n",
    "        return_tensors=\"np\",\n",
    "        truncation=True,\n",
    "        max_length=max_length\n",
    "    )\n",
    "\n",
    "    return tokenized_inputs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "id": "muwqq3dT_qs2"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "313056\n",
      "Dataset({\n",
      "    features: ['instruction', 'output', 'input_ids', 'attention_mask'],\n",
      "    num_rows: 78264\n",
      "})\n"
     ]
    }
   ],
   "source": [
    "tokenized_dataset = dataset.map(\n",
    "    tokenize_function,\n",
    "    batched=True,\n",
    "    batch_size=1,\n",
    "    drop_last_batch=True\n",
    ")\n",
    "total = sum(len(sequence) for sequence in tokenized_dataset)\n",
    "print(total)\n",
    "\n",
    "print(tokenized_dataset)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "uS2u1VSKFJ3A"
   },
   "source": [
    "#Spliting the Dataset into Train and Test Dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "id": "o-pmcKIr_qlw"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train dataset size: 62611\n",
      "Validation dataset size: 7826\n",
      "Test dataset size: 7827\n",
      "Dataset({\n",
      "    features: ['instruction', 'output', 'input_ids', 'attention_mask'],\n",
      "    num_rows: 62611\n",
      "})\n",
      "Dataset({\n",
      "    features: ['instruction', 'output', 'input_ids', 'attention_mask'],\n",
      "    num_rows: 7826\n",
      "})\n",
      "Dataset({\n",
      "    features: ['instruction', 'output', 'input_ids', 'attention_mask'],\n",
      "    num_rows: 7827\n",
      "})\n"
     ]
    }
   ],
   "source": [
    "total_samples = len(tokenized_dataset)\n",
    "train_ratio = 0.8  # 60% for training\n",
    "val_ratio = 0.1    # 20% for validation\n",
    "test_ratio = 0.1  # 20% for testing\n",
    "\n",
    "train_size = int(total_samples * train_ratio)\n",
    "val_size = int(total_samples * val_ratio)\n",
    "test_size = int(total_samples * test_ratio)\n",
    "\n",
    "# Define ranges for each split\n",
    "train_range = range(train_size)\n",
    "val_range = range(train_size, train_size + val_size)\n",
    "test_range = range(train_size + val_size, total_samples)\n",
    "\n",
    "# Create datasets based on the defined ranges\n",
    "train_dataset = tokenized_dataset.select(train_range)\n",
    "val_dataset = tokenized_dataset.select(val_range)\n",
    "test_dataset = tokenized_dataset.select(test_range)\n",
    "# Print the sizes of each dataset\n",
    "print(\"Train dataset size:\", len(train_dataset))\n",
    "print(\"Validation dataset size:\", len(val_dataset))\n",
    "print(\"Test dataset size:\", len(test_dataset))\n",
    "\n",
    "print(train_dataset)\n",
    "print(val_dataset)\n",
    "print(test_dataset)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.34.0.dev0\n"
     ]
    }
   ],
   "source": [
    "import accelerate\n",
    "print(accelerate.__version__)\n",
    "#!pip install accelerate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "12.1\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "print(torch.cuda.is_available())  # 如果返回 True，说明支持 GPU\n",
    "print(torch.version.cuda)  # 查看当前 PyTorch 使用的 CUDA 版本"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "id": "7-8OQyBZ_qhO"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Loading checkpoint shards: 100%|██████████████████████████████████████████| 2/2 [00:06<00:00,  3.24s/it]\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "import accelerate\n",
    "\n",
    "bnb_config = BitsAndBytesConfig(\n",
    "    load_in_4bit=True,\n",
    "    bnb_4bit_use_double_quant=True,\n",
    "    bnb_4bit_quant_type=\"nf4\",\n",
    "    bnb_4bit_compute_dtype=torch.bfloat16\n",
    ")\n",
    "#\"/home/rlc/搞着玩/huggingface/hub/models--codellama--CodeLlama-7b-Instruct-hf/snapshots/22cb240e0292b0b5ab4c17ccd97aa3a2f799cbed/\"\n",
    "#model = AutoModelForCausalLM.from_pretrained(\"/home/rlc/搞着玩/huggingface/hub/models--codellama--CodeLlama-7b-Instruct-hf/snapshots/22cb240e0292b0b5ab4c17ccd97aa3a2f799cbed/\"\n",
    "#)\n",
    "\n",
    "model = AutoModelForCausalLM.from_pretrained(\"/home/rlc/搞着玩/huggingface/hub/models--codellama--CodeLlama-7b-Instruct-hf/snapshots/22cb240e0292b0b5ab4c17ccd97aa3a2f799cbed/\", quantization_config=bnb_config, device_map={\"\":0})\n",
    "#model = AutoModelForCausalLM.from_pretrained(\"codellama/CodeLlama-7b-Instruct-hf\", quantization_config=bnb_config, device_map={\"\":0})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "id": "2nUrehKDECtQ"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'quant_method': <QuantizationMethod.BITS_AND_BYTES: 'bitsandbytes'>,\n",
       " '_load_in_8bit': False,\n",
       " '_load_in_4bit': True,\n",
       " 'llm_int8_threshold': 6.0,\n",
       " 'llm_int8_skip_modules': None,\n",
       " 'llm_int8_enable_fp32_cpu_offload': False,\n",
       " 'llm_int8_has_fp16_weight': False,\n",
       " 'bnb_4bit_quant_type': 'nf4',\n",
       " 'bnb_4bit_use_double_quant': True,\n",
       " 'bnb_4bit_compute_dtype': 'bfloat16',\n",
       " 'bnb_4bit_quant_storage': 'uint8',\n",
       " 'load_in_4bit': True,\n",
       " 'load_in_8bit': False}"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.config.quantization_config.to_dict()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "id": "SfKUqWtx_qZo"
   },
   "outputs": [],
   "source": [
    "# QLoRA parameters\n",
    "################################################################################\n",
    "\n",
    "# LoRA attention dimension\n",
    "lora_r = 8\n",
    "\n",
    "# Alpha parameter for LoRA scaling\n",
    "lora_alpha = 16\n",
    "\n",
    "# Dropout probability for LoRA layers\n",
    "lora_dropout = 0.05\n",
    "\n",
    "################################################################################\n",
    "# bitsandbytes parameters\n",
    "################################################################################\n",
    "\n",
    "# Activate 4-bit precision base model loading\n",
    "use_4bit = True\n",
    "\n",
    "# Compute dtype for 4-bit base models\n",
    "bnb_4bit_compute_dtype = \"float16\"\n",
    "\n",
    "# Quantization type (fp4 or nf4)\n",
    "bnb_4bit_quant_type = \"nf4\"\n",
    "\n",
    "# Activate nested quantization for 4-bit base models (double quantization)\n",
    "use_nested_quant = False\n",
    "\n",
    "################################################################################\n",
    "# TrainingArguments parameters\n",
    "################################################################################\n",
    "\n",
    "# Output directory where the model predictions and checkpoints will be stored\n",
    "output_dir = \"./results\"\n",
    "\n",
    "# Number of training epochs\n",
    "num_train_epochs = 1\n",
    "\n",
    "# Enable fp16/bf16 training (set bf16 to True with an A100)\n",
    "fp16 = True\n",
    "bf16 = False\n",
    "\n",
    "# Batch size per GPU for training\n",
    "per_device_train_batch_size = 1\n",
    "\n",
    "# Batch size per GPU for evaluation\n",
    "per_device_eval_batch_size = 1\n",
    "\n",
    "# Number of update steps to accumulate the gradients for\n",
    "gradient_accumulation_steps = 4\n",
    "\n",
    "# Enable gradient checkpointing\n",
    "gradient_checkpointing = True\n",
    "\n",
    "# Maximum gradient normal (gradient clipping)\n",
    "max_grad_norm = 0.3\n",
    "\n",
    "# Initial learning rate (AdamW optimizer)\n",
    "learning_rate = 2e-5\n",
    "\n",
    "# Weight decay to apply to all layers except bias/LayerNorm weights\n",
    "weight_decay = 0.001\n",
    "\n",
    "# Optimizer to use\n",
    "optim = \"paged_adamw_8bit\"\n",
    "#  \"paged_adamw_32bit\"\n",
    "\n",
    "# Learning rate schedule (constant a bit better than cosine)\n",
    "lr_scheduler_type = \"cosine\"\n",
    "\n",
    "# Number of training steps (overrides num_train_epochs)\n",
    "max_steps = 2000\n",
    "\n",
    "# Ratio of steps for a linear warmup (from 0 to learning rate)\n",
    "warmup_ratio = 0.03\n",
    "\n",
    "# Group sequences into batches with same length\n",
    "# Saves memory and speeds up training considerably\n",
    "group_by_length = True\n",
    "\n",
    "# Save checkpoint every X updates steps\n",
    "save_steps = 50\n",
    "\n",
    "# Log every X updates steps\n",
    "logging_steps = 10\n",
    "\n",
    "################################################################################\n",
    "# SFT parameters\n",
    "################################################################################\n",
    "\n",
    "# Maximum sequence length to use\n",
    "max_seq_length = 600\n",
    "\n",
    "# Pack multiple short examples in the same input sequence to increase efficiency\n",
    "packing = False\n",
    "\n",
    "# Load the entire model on the GPU 0\n",
    "device_map = {\"\": 0}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "id": "UXbV5npMDPrD"
   },
   "outputs": [],
   "source": [
    "def print_trainable_parameters(model):\n",
    "    \"\"\"\n",
    "    Prints the number of trainable parameters in the model.\n",
    "    \"\"\"\n",
    "    trainable_params = 0\n",
    "    all_param = 0\n",
    "    for _, param in model.named_parameters():\n",
    "        all_param += param.numel()\n",
    "        if param.requires_grad:\n",
    "            trainable_params += param.numel()\n",
    "    print(\n",
    "        f\"trainable params: {trainable_params} || all params: {all_param} || trainable%: {100 * trainable_params / all_param}\"\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "id": "atqEBChjDPnM"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "trainable params: 4194304 || all params: 3504738304 || trainable%: 0.1196752406652728\n"
     ]
    }
   ],
   "source": [
    "from peft import get_peft_model\n",
    "model.config.use_cache = False\n",
    "model.config.pretraining_tp = 1\n",
    "tokenizer.pad_token = tokenizer.eos_token\n",
    "tokenizer.padding_side = \"right\" # Fix weird overflow issue with fp16 training\n",
    "# Load LoRA configuration\n",
    "peft_config = LoraConfig(\n",
    "    lora_alpha=lora_alpha,\n",
    "    lora_dropout=lora_dropout,\n",
    "    r=lora_r,\n",
    "    bias=\"none\",\n",
    "    task_type=\"CAUSAL_LM\",\n",
    ")\n",
    "model = get_peft_model(model, peft_config)\n",
    "print_trainable_parameters(model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "id": "EWvuLyx5DPjE"
   },
   "outputs": [],
   "source": [
    "# Set training parameters\n",
    "training_arguments = TrainingArguments(\n",
    "    output_dir=output_dir,\n",
    "    num_train_epochs=num_train_epochs,\n",
    "    per_device_train_batch_size=per_device_train_batch_size,\n",
    "    gradient_accumulation_steps=gradient_accumulation_steps,\n",
    "    optim=optim,\n",
    "    save_steps=save_steps,\n",
    "    logging_steps=logging_steps,\n",
    "    learning_rate=learning_rate,\n",
    "    weight_decay=weight_decay,\n",
    "    fp16=fp16,\n",
    "    bf16=bf16,\n",
    "    max_grad_norm=max_grad_norm,\n",
    "    max_steps=max_steps,\n",
    "    warmup_ratio=warmup_ratio,\n",
    "    group_by_length=group_by_length,\n",
    "    lr_scheduler_type=lr_scheduler_type,\n",
    "    report_to=\"tensorboard\",\n",
    "    warmup_steps=30\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "#!pip install tensorboardX"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "id": "dQvrt9sVDPgD"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/rlc/miniconda3/envs/cu121/lib/python3.12/site-packages/huggingface_hub/utils/_deprecation.py:100: FutureWarning: Deprecated argument(s) used in '__init__': dataset_text_field, max_seq_length. Will not be supported from version '1.0.0'.\n",
      "\n",
      "Deprecated positional argument(s) used in SFTTrainer, please use the SFTConfig to set these arguments instead.\n",
      "  warnings.warn(message, FutureWarning)\n",
      "/home/rlc/miniconda3/envs/cu121/lib/python3.12/site-packages/trl/trainer/sft_trainer.py:280: UserWarning: You passed a `max_seq_length` argument to the SFTTrainer, the value you passed will override the one in the `SFTConfig`.\n",
      "  warnings.warn(\n",
      "/home/rlc/miniconda3/envs/cu121/lib/python3.12/site-packages/trl/trainer/sft_trainer.py:318: UserWarning: You passed a `dataset_text_field` argument to the SFTTrainer, the value you passed will override the one in the `SFTConfig`.\n",
      "  warnings.warn(\n",
      "/home/rlc/miniconda3/envs/cu121/lib/python3.12/site-packages/accelerate/accelerator.py:493: FutureWarning: `torch.cuda.amp.GradScaler(args...)` is deprecated. Please use `torch.amp.GradScaler('cuda', args...)` instead.\n",
      "  self.scaler = torch.cuda.amp.GradScaler(**kwargs)\n",
      "max_steps is given, it will override any value given in num_train_epochs\n"
     ]
    }
   ],
   "source": [
    "# Set supervised fine-tuning parameters\n",
    "trainer = SFTTrainer(\n",
    "    model=model,\n",
    "    train_dataset=train_dataset,\n",
    "    peft_config=peft_config,\n",
    "    dataset_text_field=\"instruction\",\n",
    "    max_seq_length=max_seq_length,\n",
    "    tokenizer=tokenizer,\n",
    "    args=training_arguments,\n",
    "    packing=packing,\n",
    "    data_collator=transformers.DataCollatorForLanguageModeling(tokenizer, mlm=False),\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "NLUeNV6IFqgF"
   },
   "source": [
    "#Train the LLM"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "id": "jEp6Nyw6DPcQ"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "    <div>\n",
       "      \n",
       "      <progress value='2000' max='2000' style='width:300px; height:20px; vertical-align: middle;'></progress>\n",
       "      [2000/2000 39:32, Epoch 0/1]\n",
       "    </div>\n",
       "    <table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       " <tr style=\"text-align: left;\">\n",
       "      <th>Step</th>\n",
       "      <th>Training Loss</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>10</td>\n",
       "      <td>0.512100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>20</td>\n",
       "      <td>0.653300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>30</td>\n",
       "      <td>0.713400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>40</td>\n",
       "      <td>0.891700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>50</td>\n",
       "      <td>1.318700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>60</td>\n",
       "      <td>0.530700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>70</td>\n",
       "      <td>0.627100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>80</td>\n",
       "      <td>0.698100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>90</td>\n",
       "      <td>0.882500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>100</td>\n",
       "      <td>1.495700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>110</td>\n",
       "      <td>0.519700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>120</td>\n",
       "      <td>0.607400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>130</td>\n",
       "      <td>0.628900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>140</td>\n",
       "      <td>0.728600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>150</td>\n",
       "      <td>1.112400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>160</td>\n",
       "      <td>0.487800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>170</td>\n",
       "      <td>0.616100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>180</td>\n",
       "      <td>0.634700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>190</td>\n",
       "      <td>0.727200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>200</td>\n",
       "      <td>1.194600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>210</td>\n",
       "      <td>0.499600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>220</td>\n",
       "      <td>0.552600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>230</td>\n",
       "      <td>0.621900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>240</td>\n",
       "      <td>0.736400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>250</td>\n",
       "      <td>1.166600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>260</td>\n",
       "      <td>0.444300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>270</td>\n",
       "      <td>0.540400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>280</td>\n",
       "      <td>0.581700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>290</td>\n",
       "      <td>0.653900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>300</td>\n",
       "      <td>1.147900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>310</td>\n",
       "      <td>0.448200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>320</td>\n",
       "      <td>0.557900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>330</td>\n",
       "      <td>0.523400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>340</td>\n",
       "      <td>0.610900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>350</td>\n",
       "      <td>1.038200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>360</td>\n",
       "      <td>0.463800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>370</td>\n",
       "      <td>0.505300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>380</td>\n",
       "      <td>0.541100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>390</td>\n",
       "      <td>0.605600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>400</td>\n",
       "      <td>0.976100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>410</td>\n",
       "      <td>0.427600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>420</td>\n",
       "      <td>0.523400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>430</td>\n",
       "      <td>0.537900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>440</td>\n",
       "      <td>0.693100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>450</td>\n",
       "      <td>1.249600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>460</td>\n",
       "      <td>0.497600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>470</td>\n",
       "      <td>0.502500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>480</td>\n",
       "      <td>0.578800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>490</td>\n",
       "      <td>0.646500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>500</td>\n",
       "      <td>0.944200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>510</td>\n",
       "      <td>0.430500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>520</td>\n",
       "      <td>0.516700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>530</td>\n",
       "      <td>0.525800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>540</td>\n",
       "      <td>0.604100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>550</td>\n",
       "      <td>0.948200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>560</td>\n",
       "      <td>0.467500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>570</td>\n",
       "      <td>0.511900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>580</td>\n",
       "      <td>0.508800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>590</td>\n",
       "      <td>0.603400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>600</td>\n",
       "      <td>0.944000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>610</td>\n",
       "      <td>0.419300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>620</td>\n",
       "      <td>0.542000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>630</td>\n",
       "      <td>0.541300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>640</td>\n",
       "      <td>0.618400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>650</td>\n",
       "      <td>1.041700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>660</td>\n",
       "      <td>0.445300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>670</td>\n",
       "      <td>0.511800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>680</td>\n",
       "      <td>0.491600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>690</td>\n",
       "      <td>0.594500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>700</td>\n",
       "      <td>1.043900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>710</td>\n",
       "      <td>0.433300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>720</td>\n",
       "      <td>0.471900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>730</td>\n",
       "      <td>0.531800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>740</td>\n",
       "      <td>0.619700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>750</td>\n",
       "      <td>1.067800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>760</td>\n",
       "      <td>0.478000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>770</td>\n",
       "      <td>0.515600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>780</td>\n",
       "      <td>0.514800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>790</td>\n",
       "      <td>0.537400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>800</td>\n",
       "      <td>0.990300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>810</td>\n",
       "      <td>0.419000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>820</td>\n",
       "      <td>0.482300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>830</td>\n",
       "      <td>0.522800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>840</td>\n",
       "      <td>0.588800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>850</td>\n",
       "      <td>0.887000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>860</td>\n",
       "      <td>0.420600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>870</td>\n",
       "      <td>0.495900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>880</td>\n",
       "      <td>0.525300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>890</td>\n",
       "      <td>0.556600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>900</td>\n",
       "      <td>1.058000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>910</td>\n",
       "      <td>0.440600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>920</td>\n",
       "      <td>0.506100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>930</td>\n",
       "      <td>0.529700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>940</td>\n",
       "      <td>0.665100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>950</td>\n",
       "      <td>0.976600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>960</td>\n",
       "      <td>0.430100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>970</td>\n",
       "      <td>0.529300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>980</td>\n",
       "      <td>0.514500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>990</td>\n",
       "      <td>0.617600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1000</td>\n",
       "      <td>1.228200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1010</td>\n",
       "      <td>0.461500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1020</td>\n",
       "      <td>0.500800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1030</td>\n",
       "      <td>0.499300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1040</td>\n",
       "      <td>0.604100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1050</td>\n",
       "      <td>0.925000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1060</td>\n",
       "      <td>0.397100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1070</td>\n",
       "      <td>0.534600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1080</td>\n",
       "      <td>0.508800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1090</td>\n",
       "      <td>0.649300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1100</td>\n",
       "      <td>1.050900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1110</td>\n",
       "      <td>0.417500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1120</td>\n",
       "      <td>0.448400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1130</td>\n",
       "      <td>0.541500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1140</td>\n",
       "      <td>0.557800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1150</td>\n",
       "      <td>1.068400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1160</td>\n",
       "      <td>0.412100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1170</td>\n",
       "      <td>0.501100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1180</td>\n",
       "      <td>0.511500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1190</td>\n",
       "      <td>0.607700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1200</td>\n",
       "      <td>0.994300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1210</td>\n",
       "      <td>0.416100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1220</td>\n",
       "      <td>0.488800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1230</td>\n",
       "      <td>0.517400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1240</td>\n",
       "      <td>0.630400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1250</td>\n",
       "      <td>1.103600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1260</td>\n",
       "      <td>0.400900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1270</td>\n",
       "      <td>0.457500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1280</td>\n",
       "      <td>0.505000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1290</td>\n",
       "      <td>0.543300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1300</td>\n",
       "      <td>0.948000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1310</td>\n",
       "      <td>0.447400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1320</td>\n",
       "      <td>0.485700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1330</td>\n",
       "      <td>0.499300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1340</td>\n",
       "      <td>0.590600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1350</td>\n",
       "      <td>1.055000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1360</td>\n",
       "      <td>0.402000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1370</td>\n",
       "      <td>0.476900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1380</td>\n",
       "      <td>0.540800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1390</td>\n",
       "      <td>0.604600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1400</td>\n",
       "      <td>1.029000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1410</td>\n",
       "      <td>0.428800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1420</td>\n",
       "      <td>0.497500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1430</td>\n",
       "      <td>0.506500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1440</td>\n",
       "      <td>0.596200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1450</td>\n",
       "      <td>1.031500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1460</td>\n",
       "      <td>0.466000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1470</td>\n",
       "      <td>0.484200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1480</td>\n",
       "      <td>0.556200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1490</td>\n",
       "      <td>0.581800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1500</td>\n",
       "      <td>1.023600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1510</td>\n",
       "      <td>0.471200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1520</td>\n",
       "      <td>0.481900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1530</td>\n",
       "      <td>0.522900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1540</td>\n",
       "      <td>0.604400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1550</td>\n",
       "      <td>1.010100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1560</td>\n",
       "      <td>0.426400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1570</td>\n",
       "      <td>0.463900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1580</td>\n",
       "      <td>0.510000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1590</td>\n",
       "      <td>0.622700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1600</td>\n",
       "      <td>1.052100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1610</td>\n",
       "      <td>0.454300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1620</td>\n",
       "      <td>0.450900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1630</td>\n",
       "      <td>0.498300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1640</td>\n",
       "      <td>0.629900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1650</td>\n",
       "      <td>0.931800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1660</td>\n",
       "      <td>0.444300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1670</td>\n",
       "      <td>0.473500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1680</td>\n",
       "      <td>0.539100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1690</td>\n",
       "      <td>0.548200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1700</td>\n",
       "      <td>0.911700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1710</td>\n",
       "      <td>0.390200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1720</td>\n",
       "      <td>0.480700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1730</td>\n",
       "      <td>0.582400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1740</td>\n",
       "      <td>0.616000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1750</td>\n",
       "      <td>1.035300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1760</td>\n",
       "      <td>0.476400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1770</td>\n",
       "      <td>0.486400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1780</td>\n",
       "      <td>0.491600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1790</td>\n",
       "      <td>0.567700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1800</td>\n",
       "      <td>1.036900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1810</td>\n",
       "      <td>0.409100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1820</td>\n",
       "      <td>0.532900</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1830</td>\n",
       "      <td>0.472400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1840</td>\n",
       "      <td>0.562300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1850</td>\n",
       "      <td>0.929100</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1860</td>\n",
       "      <td>0.417400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1870</td>\n",
       "      <td>0.491800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1880</td>\n",
       "      <td>0.490700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1890</td>\n",
       "      <td>0.546200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1900</td>\n",
       "      <td>0.936800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1910</td>\n",
       "      <td>0.425600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1920</td>\n",
       "      <td>0.500400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1930</td>\n",
       "      <td>0.490300</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1940</td>\n",
       "      <td>0.636800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1950</td>\n",
       "      <td>0.929400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1960</td>\n",
       "      <td>0.473700</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1970</td>\n",
       "      <td>0.484400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1980</td>\n",
       "      <td>0.518600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1990</td>\n",
       "      <td>0.572800</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2000</td>\n",
       "      <td>0.969100</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table><p>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "TrainOutput(global_step=2000, training_loss=0.6338527121543884, metrics={'train_runtime': 2376.2248, 'train_samples_per_second': 3.367, 'train_steps_per_second': 0.842, 'total_flos': 1.5525590707576013e+17, 'train_loss': 0.6338527121543884, 'epoch': 0.12777307501876667})"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.cuda.empty_cache()\n",
    "# Train model\n",
    "trainer.train()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "id": "75t1DunTQ0sJ"
   },
   "outputs": [],
   "source": [
    "# Save trained model\n",
    "trainer.model.save_pretrained(new_model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "id": "IUNtsJ4oWF1H"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Loading checkpoint shards: 100%|██████████████████████████████████████████| 2/2 [00:05<00:00,  2.99s/it]\n"
     ]
    }
   ],
   "source": [
    "# Reload model in FP16 and merge it with LoRA weights\n",
    "from transformers import AutoModelForCausalLM, AutoTokenizer\n",
    "from peft import PeftModel\n",
    "base_model = AutoModelForCausalLM.from_pretrained(\n",
    "    model_name,\n",
    "    low_cpu_mem_usage=True,\n",
    "    return_dict=True,\n",
    "    torch_dtype=torch.float16,\n",
    "    device_map=device_map,\n",
    ")\n",
    "model = PeftModel.from_pretrained(base_model, new_model)\n",
    "model = model.merge_and_unload()\n",
    "\n",
    "# Reload tokenizer to save it\n",
    "tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)\n",
    "tokenizer.add_special_tokens({'pad_token': '[PAD]'})\n",
    "tokenizer.pad_token = tokenizer.eos_token\n",
    "tokenizer.padding_side = \"right\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "id": "GRxh7w7kDPaG"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LlamaForCausalLM(\n",
       "  (model): LlamaModel(\n",
       "    (embed_tokens): Embedding(32016, 4096)\n",
       "    (layers): ModuleList(\n",
       "      (0-31): 32 x LlamaDecoderLayer(\n",
       "        (self_attn): LlamaSdpaAttention(\n",
       "          (q_proj): Linear(in_features=4096, out_features=4096, bias=False)\n",
       "          (k_proj): Linear(in_features=4096, out_features=4096, bias=False)\n",
       "          (v_proj): Linear(in_features=4096, out_features=4096, bias=False)\n",
       "          (o_proj): Linear(in_features=4096, out_features=4096, bias=False)\n",
       "          (rotary_emb): LlamaRotaryEmbedding()\n",
       "        )\n",
       "        (mlp): LlamaMLP(\n",
       "          (gate_proj): Linear(in_features=4096, out_features=11008, bias=False)\n",
       "          (up_proj): Linear(in_features=4096, out_features=11008, bias=False)\n",
       "          (down_proj): Linear(in_features=11008, out_features=4096, bias=False)\n",
       "          (act_fn): SiLU()\n",
       "        )\n",
       "        (input_layernorm): LlamaRMSNorm()\n",
       "        (post_attention_layernorm): LlamaRMSNorm()\n",
       "      )\n",
       "    )\n",
       "    (norm): LlamaRMSNorm()\n",
       "  )\n",
       "  (lm_head): Linear(in_features=4096, out_features=32016, bias=False)\n",
       ")"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.eval()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "id": "SetmCK0JZ5zI"
   },
   "outputs": [],
   "source": [
    "#model.push_to_hub(new_model, use_temp_dir=False)\n",
    "#tokenizer.push_to_hub(new_model, use_temp_dir=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "PzPwG5jVZYak"
   },
   "source": [
    "# Creating UI using Gradio\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "id": "DYG--w1pDmKs"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running on local URL:  http://127.0.0.1:7860\n",
      "\n",
      "To create a public link, set `share=True` in `launch()`.\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div><iframe src=\"http://127.0.0.1:7860/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": []
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import gradio as gr\n",
    "from transformers import pipeline\n",
    "\n",
    "def generate_response(prompt):\n",
    "\n",
    "    system_message =\"\"\"Fix the incorrect answer in the code block below. Your response must contain only the Python code that solves this problem. The clue word you entered and the solution you provided do not need to be printed, just the Python code.Please wrap your code answer using ``` \"\"\"\n",
    "\n",
    "    prompt_template= f'''\n",
    "    [INST]\n",
    "    <<sys>>\n",
    "    {system_message}\n",
    "    <</sys>>\n",
    "    {prompt}\n",
    "    [/INST]\n",
    "    '''\n",
    "    # Generate a response using the pipeline\n",
    "    pipe = pipeline(\n",
    "        \"text-generation\",\n",
    "        model=model,\n",
    "        tokenizer=tokenizer,\n",
    "        max_length=4096,\n",
    "        temperature=0.3,\n",
    "        top_p=0.95,\n",
    "        repetition_penalty=1.15\n",
    "    )\n",
    "\n",
    "    generated_text = pipe(prompt_template)[0]['generated_text']\n",
    "    # Extract content between triple backticks\n",
    "    code_start = generated_text.find(\"```\")\n",
    "    code_end = generated_text.rfind(\"```\")\n",
    "    if code_start != -1 and code_end != -1:\n",
    "        generated_text = generated_text[code_start + 3:code_end].strip()\n",
    "\n",
    "    # Remove any remaining unwanted text\n",
    "    generated_text = generated_text.replace(\"<</sys>>\", \"\").replace(\"[/INST]\", \"\").strip()\n",
    "    return generated_text\n",
    "title = \"CodeLlama-7B for Code Generation \"\n",
    "examples = [\n",
    "    'Write a python code to find the Fibonacci series.',\n",
    "    'Write a python code for Merge Sort.',\n",
    "    'Write a python code for Binary search.',\n",
    "    'Write a python code for the Longest subsequence.'\n",
    "]\n",
    "\n",
    "gr.Interface(\n",
    "    fn=generate_response,\n",
    "    inputs=gr.Textbox(label=\"Enter your prompt here...\"),\n",
    "    outputs=gr.Textbox(),\n",
    "    title=title,\n",
    "    examples=examples\n",
    ").launch()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Truncation was not explicitly activated but `max_length` is provided a specific value, please use `truncation=True` to explicitly truncate examples to max length. Defaulting to 'longest_first' truncation strategy. If you encode pairs of sequences (GLUE-style) with the tokenizer you can select this strategy more precisely by providing a specific strategy to `truncation`.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "269\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/rlc/miniconda3/envs/cu121/lib/python3.12/site-packages/transformers/generation/configuration_utils.py:515: UserWarning: `do_sample` is set to `False`. However, `temperature` is set to `0.3` -- this flag is only used in sample-based generation modes. You should set `do_sample=True` or unset `temperature`.\n",
      "  warnings.warn(\n",
      "/home/rlc/miniconda3/envs/cu121/lib/python3.12/site-packages/transformers/generation/configuration_utils.py:520: UserWarning: `do_sample` is set to `False`. However, `top_p` is set to `0.95` -- this flag is only used in sample-based generation modes. You should set `do_sample=True` or unset `top_p`.\n",
      "  warnings.warn(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "270\n",
      "271\n",
      "272\n",
      "273\n",
      "274\n",
      "275\n",
      "276\n",
      "277\n",
      "278\n",
      "279\n",
      "280\n",
      "281\n",
      "282\n",
      "283\n",
      "284\n",
      "285\n",
      "286\n",
      "287\n",
      "288\n",
      "289\n",
      "290\n",
      "291\n",
      "292\n",
      "293\n",
      "294\n",
      "295\n",
      "296\n",
      "297\n",
      "298\n",
      "299\n",
      "300\n",
      "301\n",
      "302\n",
      "303\n",
      "304\n",
      "305\n",
      "306\n",
      "307\n",
      "308\n",
      "309\n",
      "310\n",
      "311\n",
      "312\n",
      "313\n",
      "314\n",
      "315\n",
      "316\n",
      "317\n",
      "318\n",
      "319\n",
      "320\n",
      "321\n",
      "322\n",
      "323\n",
      "324\n",
      "325\n",
      "326\n",
      "327\n",
      "328\n",
      "329\n",
      "330\n",
      "331\n",
      "332\n",
      "333\n",
      "334\n",
      "335\n",
      "336\n",
      "337\n",
      "338\n",
      "339\n",
      "340\n",
      "341\n",
      "342\n",
      "343\n",
      "344\n",
      "345\n",
      "346\n",
      "347\n",
      "348\n",
      "349\n",
      "350\n",
      "351\n",
      "352\n",
      "353\n",
      "354\n",
      "355\n",
      "356\n",
      "357\n",
      "358\n",
      "359\n",
      "360\n",
      "361\n",
      "362\n",
      "363\n",
      "364\n",
      "365\n",
      "366\n",
      "367\n",
      "368\n",
      "369\n",
      "370\n",
      "371\n",
      "372\n",
      "373\n",
      "374\n",
      "375\n",
      "376\n",
      "377\n",
      "378\n",
      "379\n",
      "380\n",
      "381\n",
      "382\n",
      "383\n",
      "384\n",
      "385\n",
      "386\n",
      "387\n",
      "388\n",
      "389\n",
      "390\n",
      "391\n",
      "392\n",
      "393\n",
      "394\n",
      "395\n",
      "396\n",
      "397\n",
      "398\n",
      "399\n",
      "400\n",
      "401\n",
      "402\n",
      "403\n",
      "404\n",
      "405\n",
      "406\n",
      "407\n",
      "408\n",
      "409\n",
      "410\n",
      "411\n",
      "412\n",
      "413\n",
      "414\n",
      "415\n",
      "416\n",
      "417\n",
      "418\n",
      "419\n",
      "420\n",
      "421\n",
      "422\n",
      "423\n",
      "424\n",
      "425\n",
      "426\n",
      "427\n",
      "428\n",
      "429\n",
      "430\n",
      "431\n",
      "432\n",
      "433\n",
      "434\n",
      "435\n",
      "436\n",
      "437\n",
      "438\n",
      "439\n",
      "440\n",
      "441\n",
      "442\n",
      "443\n",
      "444\n",
      "445\n",
      "446\n",
      "447\n",
      "448\n",
      "449\n",
      "450\n",
      "451\n",
      "452\n",
      "453\n",
      "454\n",
      "455\n",
      "456\n",
      "457\n",
      "458\n",
      "459\n",
      "460\n",
      "461\n",
      "462\n",
      "463\n",
      "464\n",
      "465\n",
      "466\n",
      "467\n",
      "468\n",
      "469\n",
      "470\n",
      "471\n",
      "472\n",
      "473\n",
      "474\n",
      "475\n",
      "476\n",
      "477\n",
      "478\n",
      "479\n",
      "480\n",
      "481\n",
      "482\n",
      "483\n",
      "484\n",
      "485\n",
      "486\n",
      "487\n",
      "488\n",
      "489\n",
      "490\n",
      "491\n",
      "492\n",
      "493\n",
      "494\n",
      "495\n",
      "496\n",
      "497\n",
      "498\n",
      "499\n",
      "500\n",
      "501\n",
      "502\n",
      "503\n",
      "504\n",
      "505\n",
      "506\n",
      "507\n",
      "508\n",
      "509\n",
      "510\n",
      "511\n",
      "512\n",
      "513\n",
      "514\n",
      "515\n",
      "516\n",
      "517\n",
      "518\n",
      "519\n",
      "520\n",
      "521\n",
      "522\n",
      "523\n",
      "524\n",
      "525\n",
      "526\n",
      "527\n",
      "528\n",
      "529\n",
      "530\n",
      "531\n",
      "532\n",
      "533\n",
      "534\n",
      "535\n",
      "536\n",
      "537\n",
      "538\n",
      "539\n",
      "540\n",
      "541\n",
      "542\n",
      "543\n",
      "544\n",
      "545\n",
      "546\n",
      "547\n",
      "548\n",
      "549\n",
      "550\n",
      "551\n",
      "552\n",
      "553\n",
      "554\n",
      "555\n",
      "556\n",
      "557\n",
      "558\n",
      "559\n",
      "560\n",
      "561\n",
      "562\n",
      "563\n",
      "564\n",
      "565\n",
      "566\n",
      "567\n",
      "568\n",
      "569\n",
      "570\n",
      "571\n",
      "572\n",
      "573\n",
      "574\n",
      "575\n",
      "576\n",
      "577\n",
      "578\n",
      "579\n",
      "580\n",
      "581\n",
      "582\n",
      "583\n",
      "584\n",
      "585\n",
      "586\n",
      "587\n",
      "588\n",
      "589\n",
      "590\n",
      "591\n",
      "592\n",
      "593\n",
      "594\n",
      "595\n",
      "596\n",
      "597\n",
      "598\n",
      "599\n",
      "600\n",
      "601\n",
      "602\n",
      "603\n",
      "604\n",
      "605\n",
      "606\n",
      "607\n",
      "608\n",
      "609\n",
      "610\n",
      "611\n",
      "612\n",
      "613\n",
      "614\n",
      "615\n",
      "616\n",
      "617\n",
      "618\n",
      "619\n",
      "620\n",
      "621\n",
      "622\n",
      "623\n",
      "624\n",
      "625\n",
      "626\n",
      "627\n",
      "628\n",
      "629\n",
      "630\n",
      "631\n",
      "632\n",
      "633\n",
      "634\n",
      "635\n",
      "636\n",
      "637\n",
      "638\n",
      "639\n",
      "640\n",
      "641\n",
      "642\n",
      "643\n",
      "644\n",
      "645\n",
      "646\n",
      "647\n",
      "648\n",
      "649\n",
      "650\n",
      "651\n",
      "652\n",
      "653\n",
      "654\n",
      "655\n",
      "656\n",
      "657\n",
      "658\n",
      "659\n",
      "660\n",
      "661\n",
      "662\n",
      "663\n",
      "664\n",
      "665\n",
      "666\n",
      "667\n",
      "668\n",
      "669\n",
      "670\n",
      "671\n",
      "672\n",
      "673\n",
      "674\n",
      "675\n",
      "676\n",
      "677\n",
      "678\n",
      "679\n",
      "680\n",
      "681\n",
      "682\n",
      "683\n",
      "684\n",
      "685\n",
      "686\n",
      "687\n",
      "688\n",
      "689\n",
      "690\n",
      "691\n",
      "692\n",
      "693\n",
      "694\n",
      "695\n",
      "696\n",
      "697\n",
      "698\n",
      "699\n",
      "700\n",
      "701\n",
      "702\n",
      "703\n",
      "704\n",
      "705\n",
      "706\n",
      "707\n",
      "708\n",
      "709\n",
      "710\n",
      "711\n",
      "712\n",
      "713\n",
      "714\n",
      "715\n",
      "716\n",
      "717\n",
      "718\n",
      "719\n",
      "720\n",
      "721\n",
      "722\n",
      "723\n",
      "724\n",
      "725\n",
      "726\n",
      "727\n",
      "728\n",
      "729\n",
      "730\n",
      "731\n",
      "732\n",
      "733\n",
      "734\n",
      "735\n",
      "736\n",
      "737\n",
      "738\n",
      "739\n",
      "740\n",
      "741\n",
      "742\n",
      "743\n",
      "744\n",
      "745\n",
      "746\n",
      "747\n",
      "748\n",
      "749\n",
      "750\n",
      "751\n",
      "752\n",
      "753\n",
      "754\n",
      "755\n",
      "756\n",
      "757\n",
      "758\n",
      "759\n",
      "760\n"
     ]
    }
   ],
   "source": [
    "import gradio as gr\n",
    "import json\n",
    "from transformers import pipeline #, AutoTokenizer \n",
    "def generate_response(prompt):\n",
    "    system_message =\"\"\"Fix the incorrect answer in the code block below. Your response must contain only the Python code that solves this problem. The clue word you entered and the solution you provided do not need to be printed, just the Python code.Please wrap your code answer using ``` \"\"\"\n",
    "\n",
    "    prompt_template= f'''\n",
    "    [INST]\n",
    "    <<sys>>\n",
    "    {system_message}\n",
    "    <</sys>>\n",
    "    {prompt}\n",
    "    [/INST]\n",
    "    '''\n",
    "    # Generate a response using the pipeline\n",
    "    pipe = pipeline(\n",
    "        \"text-generation\",\n",
    "        model=model,\n",
    "        tokenizer=tokenizer,\n",
    "        max_length=5900,\n",
    "        temperature=0.3,\n",
    "        top_p=0.95,\n",
    "        repetition_penalty=1.15\n",
    "        #device=0\n",
    "    )\n",
    "\n",
    "    generated_text = pipe(prompt_template)[0]['generated_text']\n",
    "    key_phrase = \"```\"\n",
    "    key_position = generated_text.find(key_phrase)\n",
    "    if key_position != -1:\n",
    "      generated_text = generated_text[key_position + len(key_phrase):].strip()\n",
    "    code_start = generated_text.find(\"```\")\n",
    "    code_end = generated_text.rfind(\"```\")\n",
    "    if code_start != -1 and code_end != -1:\n",
    "        generated_text = generated_text[code_start + 3:code_end].strip()\n",
    "    generated_text = generated_text.replace(\"<</sys>>\", \"\").replace(\"[/INST]\", \"\").strip()\n",
    "    return generated_text\n",
    "# 打开原始 jsonl 文件进行读取，并打开一个新的 jsonl 文件进行写入\n",
    "a=268\n",
    "with open(r'A榜测试数据268_1056.jsonl', 'r', encoding='utf-8') as infile, open('output_have_que6.jsonl', 'w', encoding='utf-8') as outfile:\n",
    "    for line in infile:\n",
    "        a=a+1\n",
    "      \n",
    "        data = json.loads(line.strip())  # 解析每一行的 JSON 对象\n",
    "        bad_solution = data['bad_solution']\n",
    "        print(a)\n",
    "           # 调用生成响应的函数\n",
    "        data['output'] = generate_response(bad_solution)\n",
    "        del data['bad_solution'] \n",
    "        outfile.write(json.dumps(data,ensure_ascii=False) + '\\n',)\n",
    "        torch.cuda.empty_cache()  \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "accelerator": "GPU",
  "colab": {
   "gpuType": "T4",
   "provenance": []
  },
  "kernelspec": {
   "display_name": "cu121",
   "language": "python",
   "name": "cu121"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
